package host.skiree.nettydemo.client.handler;

import host.skiree.nettydemo.client.service.MessageClientHandlerFactory;
import host.skiree.nettydemo.message.*;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author anorak
 */
@Slf4j
public class DemoClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * CountDownLatch允许一个或者多个线程去等待其他线程完成操作,参考 https://blog.csdn.net/hbtj_1216/article/details/109655995
     */
    public static CountDownLatch WAIT_FOR_LOGIN = new CountDownLatch(1);

    /**
     * 记录是否客户端已经登录
     */
    public static AtomicBoolean LOGIN = new AtomicBoolean(false);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        new Thread( () -> {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入您的用户名 : ");
            String userName = scanner.nextLine();
            System.out.print("请输入您的密码 : ");
            String passWord = scanner.nextLine();
            ctx.writeAndFlush(new LoginRequestMessage(userName, passWord));
            System.out.println("正在登陆中......");
            try{
                WAIT_FOR_LOGIN.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (!LOGIN.get()){
                ctx.channel().close();
                return;
            }
            while (true){
                System.out.println("==================================");
                System.out.println("ulist");
                System.out.println("send [username] [content]");
                System.out.println("gcreate [group name] [m1,m2,m3...]");
                System.out.println("gsend [group name] [content]");
                System.out.println("guser [group name]");
                System.out.println("gjoin [group name]");
                System.out.println("gquit [group name]");
                System.out.println("quit");
                System.out.println("==================================");
                String command = scanner.nextLine();
                String[] s = command.split(" ");
                switch (s[0]){
                    case "ulist":
                        ctx.writeAndFlush(new UserListRequestMessage());
                        break;
                    case "send":
                        ctx.writeAndFlush(new ChatRequestMessage(userName, s[1], s[2]));
                        break;
                    case "gcreate":
                        Set<String> set = new HashSet<>(Arrays.asList(s[2].split(",")));
                        set.add(userName);
                        ctx.writeAndFlush(new GroupCreateRequestMessage(s[1], set));
                        break;
                    case "glist":
                        ctx.writeAndFlush(new GroupListRequestMessage());
                        break;
                    case "gsend":
                        ctx.writeAndFlush(new GroupChatRequestMessage(userName, s[1], s[2]));
                        break;
                    case "guser":
                        ctx.writeAndFlush(new GroupMembersRequestMessage(s[1]));
                        break;
                    case "gjoin":
                        ctx.writeAndFlush(new GroupJoinRequestMessage(userName, s[1]));
                        break;
                    case "gquit":
                        ctx.writeAndFlush(new GroupQuitRequestMessage(userName, s[1]));
                        break;
                    case "quit":
                        ctx.channel().close();
                        return;
                }
            }
        }).start();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        // 处理心跳事件
        if ( evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent) evt;
            // 触发了读空闲事件
            if (event.state() == IdleState.WRITER_IDLE) {
//                log.debug("已经 2s 没有写数据了");
                ctx.writeAndFlush(new PingMessage());
            }
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = (Message) msg;
        MessageClientHandlerFactory.MESSAGE_HANDLER
                .get(message.getMessageType())
                .handleMessage(ctx, message);
    }

}
